package cn.lili.modules.order.order.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.distribution.client.DistributionClient;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.dto.DistributionApplyDTO;
import cn.lili.modules.distribution.entity.dto.DistributionSearchParams;
import cn.lili.modules.distribution.entity.enums.DistributionStatusEnum;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.order.order.entity.dos.RankingDistribution;
import cn.lili.modules.order.order.entity.dos.RankingScoreDetails;
import cn.lili.modules.order.order.entity.dto.RankingDistributionDTO;
import cn.lili.modules.order.order.entity.dto.RankingScoreDetailsDTO;
import cn.lili.modules.order.order.entity.vo.DistributionAndGrowAwardVO;
import cn.lili.modules.order.order.entity.vo.RankingDistributionVO;
import cn.lili.modules.order.order.mapper.RankingDistributionMapper;
import cn.lili.modules.order.order.service.IRankingDistributionService;
import cn.lili.modules.order.order.service.IRankingScoreDetailsService;
import cn.lili.mybatis.util.PageUtil;
import com.alibaba.fastjson.JSONObject;
import com.api.UserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pojos.FyUserInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 排名活动-店主表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-12-25
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RankingDistributionServiceImpl extends ServiceImpl<RankingDistributionMapper, RankingDistribution> implements IRankingDistributionService {
    private final UserClient userClient;
    private final UserApi userApi;
    private final IRankingScoreDetailsService rankingScoreDetailsService;
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public RankingDistribution applyDistribution(DistributionApplyDTO distributionApplyDTO) {
        String memberId = Objects.requireNonNull(UserContext.getCurrentUser()).getId();
        //判断用户是否申请过分销
        QueryWrapper<RankingDistribution> queryWrapper = new QueryWrapper();
        queryWrapper.eq("member_id", memberId);
        RankingDistribution distribution = baseMapper.selectOne(queryWrapper);
//        如果店主非空并未审核则提示用户请等待，如果店主为拒绝状态则重新提交申请
        if (Optional.ofNullable(distribution).isPresent()) {
            if (distribution.getDistributionStatus().equals(DistributionStatusEnum.APPLY.name())) {
                throw new ServiceException("已申请店主,请等待审核");
            } else if (distribution.getDistributionStatus().equals(DistributionStatusEnum.REFUSE.name())) {
                distribution.setDistributionStatus(DistributionStatusEnum.APPLY.name());
                BeanUtil.copyProperties(distributionApplyDTO, distribution);
                this.updateById(distribution);
                return distribution;
            }
        }
        //如果未申请店主则新增进行申请
        //获取当前登录用户
        User member = userClient.getById(memberId);
        //新建店主
        distribution = new RankingDistribution(member.getId(), member.getNickName(), distributionApplyDTO);
        //添加店主
        this.save(distribution);

        return distribution;
    }



    @Override
    public Page<RankingDistribution> raningDistributionPage(DistributionSearchParams distributionSearchParams, PageVO page) {
        return this.page(PageUtil.initPage(page), distributionSearchParams.queryWrapper());
    }

    @Override
    public RankingDistribution getRankingDistribution() {
        String userId = UserContext.getCurrentUser().getId();
        return this.getOne(new LambdaQueryWrapper<RankingDistribution>().eq(RankingDistribution::getMemberId, userId).last("limit 1"));

    }


    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean audit(String id, String status) {
        //根据id获取店主
        RankingDistribution distribution = this.getById(id);
        if (Optional.ofNullable(distribution).isPresent()) {
            if (status.equals(DistributionStatusEnum.PASS.name())) {
                distribution.setDistributionStatus(DistributionStatusEnum.PASS.name());
                //查询上级信息
                User user = userClient.getById(distribution.getMemberId());
                if (null != user) {
                    String parentOpenId = userApi.getParent(user.getOpenId());
                    if (StringUtils.isNotEmpty(parentOpenId)) {
                        //查询店长的下级人数
                        String childCount = userApi.getChildCount(parentOpenId);
                        distribution.setChildCount(StringUtils.isNotEmpty(childCount) ? Integer.valueOf(childCount) : 0);
                        User parentUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
                        //赋值上级id,邀请人ID
                        distribution.setParentId(null != parentUser ? parentUser.getId() : null);
                    }
                }

            } else {
                distribution.setDistributionStatus(DistributionStatusEnum.REFUSE.name());
            }
            //审核时间
            distribution.setAuditTime(new Date());
            return this.updateById(distribution);
        }
        return false;
    }
    /**
     * 等级下拉框数据
     * @return
     */
    @Override
    public List<Object> getDistributionLevelList() {
        List<Object> levelList = baseMapper.selectObjs(this.toQueryWrapper(new RankingDistributionDTO()).select(RankingDistribution::getLevel)
                .eq(RankingDistribution::getDistributionStatus, DistributionStatusEnum.PASS.name()).eq(RankingDistribution::getDeleteFlag, Boolean.FALSE)
                .groupBy(RankingDistribution::getLevel));
        return levelList;
    }
    /**
     * 店主排名活动-店主列表
     * @param dto
     * @return
     */
    @Override
    public ResultMessage<Page<RankingDistributionVO>> getRankingStoreList(RankingDistributionDTO dto) {
        if (StringUtils.isNotEmpty(dto.getSortOrder()) && dto.getSortOrder().contains("normal")) {
            dto.setSortOrder(null);
        }
        dto.setDistributionStatus(DistributionStatusEnum.PASS.name());
        Page<RankingDistributionVO> page = baseMapper.selectDistributionVOPage(new Page<>(dto.getPageNumber(), dto.getPageSize()), dto);
        if (CollUtil.isNotEmpty(page.getRecords())) {
            List<String> memberIds = page.getRecords().stream().filter(e -> StringUtils.isEmpty(e.getFyName())).map(a -> a.getUserId()).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(memberIds)) {
                List<User> userInfos = userClient.selectUserListByIds(memberIds);
                if (CollUtil.isNotEmpty(userInfos)) {
                    //更新用户昵称和账号
                    List<RankingDistribution> paramRankingDistributions = new ArrayList<>();
                    for (User childUser : userInfos) {
                        for (RankingDistributionVO vo : page.getRecords()) {
                            if (childUser.getId().equals(vo.getUserId())) {
                                vo.setFyName(childUser.getFyName());
                                vo.setAccount(childUser.getAccount());

                                RankingDistribution rd = new RankingDistribution();
                                rd.setId(vo.getId());
                                rd.setFyName(childUser.getFyName());
                                rd.setAccount(childUser.getAccount());
                                paramRankingDistributions.add(rd);
                            }
                        }
                    }
                    //更新到店主表
                    if (paramRankingDistributions.size() > 0) {
                        this.updateBatchById(paramRankingDistributions);
                    }

                }
            }
            return ResultUtil.data(page);
        }
        return ResultUtil.data(new Page<>());
    }

    /**
     *  店主排名活动-店主详情 查询QueryWrapper
     * @param dto
     * @return
     */
    private LambdaQueryWrapper<RankingDistribution> toQueryWrapper(RankingDistributionDTO dto) {
        LambdaQueryWrapper<RankingDistribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RankingDistribution::getDeleteFlag, Boolean.FALSE);
        //用户id
        if (StringUtils.isNotEmpty(dto.getUserId())) {
            queryWrapper.eq(RankingDistribution::getMemberId, dto.getUserId());
        }
        //上级id
        if (StringUtils.isNotEmpty(dto.getParentId())) {
            queryWrapper.eq(RankingDistribution::getParentId, dto.getParentId());
        }
        //用户昵称
        if (StringUtils.isNotEmpty(dto.getNickName())) {
            queryWrapper.eq(RankingDistribution::getMemberName, dto.getNickName());
        }
        //开通时间
        if (StringUtils.isNotEmpty(dto.getStartTime()) && StringUtils.isNotEmpty(dto.getEndTime())) {
            queryWrapper.ge(RankingDistribution::getAuditTime, dto.getStartTime());
            queryWrapper.le(RankingDistribution::getAuditTime, dto.getEndTime());
        }
        //等级
        if (null != dto.getLevel() && dto.getLevel() > 0) {
            queryWrapper.eq(RankingDistribution::getLevel, dto.getLevel());
        }
        return queryWrapper;
    }

    /**
     * 店主列表下级明细详情
     * @param dto
     * @return
     */
    @Override
    public ResultMessage<Page<RankingDistributionVO>> getLowerDistributeionDetails(RankingDistributionDTO dto) {
        dto.setDistributionStatus(DistributionStatusEnum.PASS.name());
        if (StringUtils.isEmpty(dto.getUserId())) {
            //初始页面的时候,传值给parentId ,并且userId为null
            dto.setUserId(null);
        }
        //查询积分明细表里的下级人数
        RankingScoreDetailsDTO scoreDetailsDTO = new RankingScoreDetailsDTO();
        if (StringUtils.isNotEmpty(dto.getParentId())) {
            scoreDetailsDTO.setUserId(dto.getParentId());
        }
        if (StringUtils.isNotEmpty(dto.getUserId())) {
            User buyerUser = userClient.getByUserName(dto.getUserId(), SceneEnums.MEMBER.name());
            scoreDetailsDTO.setBuyerUserId(buyerUser != null ? buyerUser.getId() : dto.getUserId());
        }
        scoreDetailsDTO.setPageNumber(dto.getPageNumber());
        scoreDetailsDTO.setPageSize(dto.getPageSize());
        Page<RankingScoreDetails> detailsPage = rankingScoreDetailsService.getDistributeionSubCommissDetails(scoreDetailsDTO).getResult();
        if (null != detailsPage && CollUtil.isNotEmpty(detailsPage.getRecords())) {
            //筛选出byuserid
            List<String> buyerUserIds = detailsPage.getRecords().stream().map(RankingScoreDetails::getBuyerUserId).distinct().collect(Collectors.toList());
            if(CollUtil.isNotEmpty(buyerUserIds)) {
                dto.setUserIds(buyerUserIds);
            }
        }
        //根据id查下级数据
        Page<RankingDistributionVO> page = baseMapper.getLowerDistributeionDetails(new Page<>(dto.getPageNumber(), dto.getPageSize()), dto);
        if (CollUtil.isEmpty(detailsPage.getRecords()) && CollUtil.isEmpty(page.getRecords())) {
            return ResultUtil.data(new Page<>());
        }
        if (CollUtil.isEmpty(page.getRecords()) && CollUtil.isNotEmpty(detailsPage.getRecords())) {
            page.setRecords(new ArrayList<RankingDistributionVO>());
            for (RankingScoreDetails details : detailsPage.getRecords()) {
                RankingDistributionVO vo = new RankingDistributionVO();
                vo.setUserId(details.getBuyerUserId());
                page.getRecords().add(vo);
            }
        }

        //去重
        page.setRecords(page.getRecords().stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getUserId()))), ArrayList::new)));

        //查询下级userid的账号和昵称
        List<String> buyerUserIds = page.getRecords().stream().map(RankingDistributionVO::getUserId).distinct().collect(Collectors.toList());
        List<User> childUserInfos = userClient.selectUserListByIds(buyerUserIds);
        if(CollUtil.isNotEmpty(childUserInfos)){
            for (User childUser : childUserInfos) {
                for (RankingDistributionVO vo : page.getRecords()) {
                    if (childUser.getId().equals(vo.getUserId())) {
                        vo.setChildFyName(childUser.getFyName());
                        vo.setChildAccount(childUser.getAccount());
                    }
                }
            }
        }
        return ResultUtil.data(page);
    }

    /**
     * 分页获取成长奖励列表
     * @param dto
     * @return
     */
    @Override
    public Page<DistributionAndGrowAwardVO> selectDistributionPageListNew(RankingDistributionDTO dto) {

        Page<DistributionAndGrowAwardVO> page = new Page();
        if (StringUtils.isNotEmpty(dto.getGrowAwardId()) && dto.getGrowAwardId().equals("0")) {
            page = baseMapper.selectDistributionPageListNew0(new Page<>(dto.getPageNumber(), dto.getPageSize()), dto);
        }else{
            page = baseMapper.selectDistributionPageListNew1(new Page<>(dto.getPageNumber(), dto.getPageSize()), dto);
        }
        return page;
    }


    /** ==========================================   以下是原feign controller里的代码 =============================*/


    @Override
    public int addGrossCommission(String id, BigDecimal scoreScale) {
        RankingDistribution distribution = baseMapper.selectById(id);
        if (distribution == null) {
            log.error("未获取到店主信息 ：" + id);
            return 0;
        }
        RankingDistribution param = new RankingDistribution();
        param.setId(id);
        param.setGrossCommission(scoreScale);
//      return distributionService.updateAdd(distribution);
        return baseMapper.updateRankingDistribution(param);
    }


    @Override
    public int updateRankingDistribution(RankingDistribution param) {
        return baseMapper.updateRankingDistribution(param);
    }

    /**
     * 根据 memberId获取店主信息
     * @param memberId
     * @return
     */
    @Override
    public RankingDistribution getRankingDistributionByMemberId(String memberId) {
        LambdaQueryWrapper<RankingDistribution> query = new LambdaQueryWrapper<>();
        query.eq(RankingDistribution::getMemberId, memberId);
        query.eq(RankingDistribution::getDeleteFlag, Boolean.FALSE);
        query.last("limit 1");
        return baseMapper.selectOne(query);
    }

    @Autowired
    private DistributionClient distributionClient;
    /**
     * 刷RankingDistribution数据
     * @return
     */
    @Override
    public Object syncRankingDistributionData() {
        //获取Distribution所有通过审核的数据
        List<Distribution> distributionList = distributionClient.getDistributionList(new Distribution() {{
            setDistributionStatus(DistributionStatusEnum.PASS.name());
        }});
        Map<String, Object> resutlMap = new HashMap<>(3);
        log.info("#syncRankingDistributionData# 查到的Distribution数据条数,{}条", distributionList.size());
        if (CollUtil.isNotEmpty(distributionList)) {
            resutlMap.put("查到的Distribution数据:", distributionList.size());
            List<String> memberIds = distributionList.stream().map(Distribution::getMemberId).distinct().collect(Collectors.toList());
            log.info("#syncRankingDistributionData# 筛选memberIds,{}条", memberIds.size());
            List<User> users = userClient.selectUserListByIds(memberIds);
            log.info("#syncRankingDistributionData# 根据memberIds查询到users,{}条", users.size());
            //声明要保存的集合
            List<RankingDistribution> rankingDistrs = new ArrayList<>();

            for (Distribution dis : distributionList) {
                for (User user : users) {
                    FyUserInfo fyUserInfo = userApi.getFyUserInfo(user.getAccount());
                    log.info("#syncRankingDistributionData# 根据openid查询到fyUserInfo,参数为:{},结果为:{}", user.getOpenId(), JSONObject.toJSONString(fyUserInfo));
                    if (dis.getMemberId().equals(user.getId()) && fyUserInfo != null) {
                        RankingDistribution rankingDistribution = new RankingDistribution();
                        BeanUtil.copyProperties(dis, rankingDistribution);
                        //飞语信息account,fyName
                        rankingDistribution.setAccount(fyUserInfo.getAccount());
                        rankingDistribution.setFyName(fyUserInfo.getFyName());
                        //下级人数
                        String childCount = userApi.getChildCount(user.getOpenId());
                        rankingDistribution.setChildCount(StringUtils.isNotEmpty(childCount) ? Integer.valueOf(childCount) : 0);
                        log.info("#syncRankingDistributionData# 根据openid查询下级人数,参数为:{},结果为:{}", user.getOpenId(), childCount);
                        //上级信息
                        String parentOpenId = userApi.getParent(user.getOpenId());
                        log.info("#syncRankingDistributionData# 根据openid查询上级信息,参数为:{},结果为:{}", user.getOpenId(), parentOpenId);
                        if (StringUtils.isNotEmpty(parentOpenId)) {
                            User parentUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
                            log.info("#syncRankingDistributionData# 根据openid查询上级商城user信息,参数为:{},结果为:{}", parentOpenId, JSONObject.toJSONString(parentUser));
                            if (null != parentUser) {
                                rankingDistribution.setParentId(parentUser.getId());
                                rankingDistribution.setParentFyName(parentUser.getFyName());
                            }
                        }
                        rankingDistribution.setGrossCommission(new BigDecimal(0));
                        rankingDistrs.add(rankingDistribution);
                    }
                }
            }
            resutlMap.put("需要保存的数据条数:", rankingDistrs.size());
            if (CollUtil.isNotEmpty(rankingDistrs)) {
                boolean flag = this.saveBatch(rankingDistrs);
                resutlMap.put("保存数据:", flag ? "成功" : "失败");
            }
        }
        return resutlMap;
    }
}
